package com.crawel.tiantianyingqiu;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSONObject;
import com.microsoft.playwright.*;
import com.microsoft.playwright.options.LoadState;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

/**
 * @program: SpringBootDemos
 * @description: 天天赢球的 爬虫
 * @author: Kangsen
 * @create: 2022-06-07 15:22
 **/
public class Crawler {
    private final static int CONNECTION_TIME_OUT = 6000;

    public static void main(String[] args) {

        /************************************既嗨爬数据*******************************************/
        //crwalJH();

        //playWright();

        crawlTT();
    }

    //既嗨
    public static void crwalJH(){
        HashMap<String, String> header = new HashMap<>();
        header.put("Content-Type","application/json");
        header.put("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.33");
        header.put("Accept","application/json, text/plain, */*");
        header.put("Accept-Encoding","gzip, deflate, br");
        header.put("Referer","https://www.jihai8.com/");
        header.put("Origin","https://www.jihai8.com");
        //获取配置文件

        String body = "";
        String param = "?companyId=3";
        // 请求地址
        String url = "https://api-live.jihai8.com/newapi/football/oddsList" + param;
        Map<String, Object> map = doGet(url, "utf-8", header, "");
        //获取的是联赛列表
        System.out.println(map.get("res"));
    }
    //天天赢球
    public static void crawlTT(){
        HashMap<String, String> header = new HashMap<>();
        header.put("Content-Type","application/json");
        header.put("User-Agent","Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36 Edg/102.0.5005.63");
        header.put("Accept","application/json, text/plain, */*");
        header.put("Accept-Encoding","gzip, deflate, br");
        header.put("Referer","http://tt.aicai.com/");
        header.put("Origin","http://tt.aicai.com/");
        Map<String,Object> bodyMap = new HashMap<>();
        bodyMap.put("timestamp",System.currentTimeMillis());
        bodyMap.put("verifyStr","");
        //bodyMap.put("simple",1);//
        //bodyMap.put("oddsCompany",6);//
        bodyMap.put("apiName","getMatchListByDate");
        bodyMap.put("game","0");
        bodyMap.put("jcTurnFlag",1);
        bodyMap.put("pageNo",1);
        bodyMap.put("pageSize",20);
        String body = JSONObject.toJSONString(bodyMap);
        // 请求地址
        String url = "http://tt.aicai.com/sportdata/f?agentId=2335059&platform=wap&appVersion=7.4.1&from=jcob&jcobSessionId=06878837-f92e-508e-80aa-2878f3536745";
        Map<String, Object> map = doPost(url, body, "utf-8", header, "");
        //获取的是联赛列表
        Object data = map.containsKey("res") ? map.get("res") : null;
        //System.out.println("联赛列表数据:"+data);
        JSONObject jsonObject = JSONObject.parseObject(String.valueOf(data));
        System.out.println("联赛列表数据:"+jsonObject);
        //足球 全部 列表

        Assert.isTrue(false,"先退出 不执行后面的");
        //获取时间直播信息
        //url = "http://tt.aicai.com/sportdata/f?agentId=2335059&platform=wap&appVersion=7.4.1&from=jcob&jcobSessionId=06878837-f92e-508e-80aa-2878f353676d";
        body = "{timestamp: 1654658962388, verifyStr: \"\", apiName: \"getMatchEvent\", matchId: 5281565}";
        map =  doPost(url, body, "utf-8", header, "");
        //获取的是事件直播
        System.out.println("----------------------elapsedTime:比赛时间  eventType:3黄牌   11换人---------------------------------------");
        System.out.println(map.get("res"));

        //比分
        //url = "http://tt.aicai.com/sportdata/f?agentId=2335059&platform=wap&appVersion=7.4.1&from=jcob&jcobSessionId=06878837-f92e-508e-80aa-2878f353676d";
        body = "{apiName: \"getMatchListLiveScore\",jcTurnFlag: 0,matchIdList: [5281565],timestamp: 1654670286682,verifyStr: \"\"}";
        map =  doPost(url, body, "utf-8", header, "");
        //获取比分
        System.out.println("----------------------比分数据 card: 红-黄 红-黄---------------------------------------");
        System.out.println(map.get("res"));

        //直播动画
        body = "{apiName: \"getFtLeisuMatchVideo\",matchIds:[5281565],timestamp:1654670746824,verifyStr:\"\"}";
        map =  doPost(url, body, "utf-8", header, "");
        //获取直播动画
        System.out.println("----------------------直播动画地址---------------------------------------");
        System.out.println(map.get("res"));

        //getMatchStanding
        body = "{timestamp: 1654742831547, verifyStr: \"\", apiName: \"getMatchStanding\", matchId: 5281524}";
        map =  doPost(url, body, "utf-8", header, "");
        //获取直播动画
        System.out.println("----------------------getMatchStanding---------------------------------------");
        System.out.println(map.get("res"));

    }


    /**
     * 使用自动化测试工具模拟浏览器
     */
    public static void playWright(){
        Consumer<Response> onResponse = interceptedResponse -> {
            System.out.println("A response was made: " + interceptedResponse);
        };
        try (Playwright playwright = Playwright.create()) {
            Browser browser = playwright.chromium().launch();
            BrowserContext context = browser.newContext();
            Page page = context.newPage();
            page.onResponse(onResponse);
            page.navigate("http://tt.aicai.com/#/match-detail/ft/5296301?from=1");
            page.waitForLoadState(LoadState.NETWORKIDLE);
            System.out.println(page.content());
        }
    }


    /**
     * Get方式请求
     * @param pageUrl 请求地址
     * @param charset 编码方式
     * @param params  参数
     * @param proxyIp 代理IP
     * @return
     */
    public static Map<String, Object> doGet(String pageUrl, String charset, Map<String, String> params, String proxyIp) {
        Map<String, Object> map = new HashMap<String, Object>();
        String result = null;
        if (null == charset) {
            charset = "utf-8";
        }
        //设置绕过SSL请求验证
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).build();
        try {
            URL url = new URL(pageUrl);
            //设置代理协议
            HttpHost target = new HttpHost(url.getHost(), url.getDefaultPort(), url.getProtocol());
            HttpHost proxy = null;
            if(StringUtils.isNotBlank(proxyIp)){
                proxy = new HttpHost(proxyIp.split(":")[0], Integer.parseInt(proxyIp.split(":")[1]));
            }
            RequestConfig config = null;
            if(proxy != null){
                config = RequestConfig.custom().setProxy(proxy).setConnectTimeout(CONNECTION_TIME_OUT)
                        .setConnectionRequestTimeout(CONNECTION_TIME_OUT).setSocketTimeout(CONNECTION_TIME_OUT).build();
            }else{
                config = RequestConfig.custom().setConnectTimeout(CONNECTION_TIME_OUT)
                        .setConnectionRequestTimeout(CONNECTION_TIME_OUT).setSocketTimeout(CONNECTION_TIME_OUT).build();
            }
            HttpGet httpget = new HttpGet(url.toString());
            httpget.setConfig(config);
            try {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    httpget.addHeader(entry.getKey(), entry.getValue());
                }
            } catch (Exception e) {
            }
            CloseableHttpResponse response = null;
            try {
                response = httpclient.execute(target, httpget);
                if (response != null) {
                    HttpEntity resEntity = response.getEntity();
                    if (resEntity != null) {
                        result = EntityUtils.toString(resEntity, charset);
                        map.put("res", result);
                    }
                    Header[] headerinfo = response.getAllHeaders();
                    map.put("headerinfo", headerinfo);
                }
            } catch (Exception e) {
                map.put("res", "error");
                e.printStackTrace();
            } finally {
                try {
                    response.close();
                } catch (NullPointerException e) {
                    map.put("res", "error");
                    e.printStackTrace();
                }
            }
        }catch (ConnectTimeoutException | SocketTimeoutException e) {
            map.put("res", "error");
            return map;
        }catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }
    /**
     * Post方式请求
     * @param pageUrl 请求地址
     * @param params 请求参数
     * @param charset 编码方式
     * @param header 请求头
     * @param proxyIp 代理IP
     * @return
     */
    public static Map<String, Object> doPost(String pageUrl, String params, String charset, Map<String, String> header, String proxyIp) {
        System.out.println("===========================================【POST请求信息】==================================================");
        System.out.println("||  【POST地址】-{}"+pageUrl);
        System.out.println("||  【请求参数】{}"+params);
        System.out.println("===========================================================================================================");
        Map<String, Object> resMap = new HashMap<String, Object>();
        String result = null;
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).build();
        try {
            URL url = new URL(pageUrl);
            HttpHost target = new HttpHost(url.getHost(), url.getDefaultPort(), url.getProtocol());
            RequestConfig config = null;
            if(StringUtils.isNotBlank(proxyIp)){
                HttpHost proxy = new HttpHost(proxyIp.split(":")[0], Integer.parseInt(proxyIp.split(":")[1]));
                config = RequestConfig.custom().setProxy(proxy).setConnectTimeout(CONNECTION_TIME_OUT)
                        .setConnectionRequestTimeout(CONNECTION_TIME_OUT).setSocketTimeout(CONNECTION_TIME_OUT).build();
            }else{
                config = RequestConfig.custom().setConnectTimeout(CONNECTION_TIME_OUT)
                        .setConnectionRequestTimeout(CONNECTION_TIME_OUT).setSocketTimeout(CONNECTION_TIME_OUT).build();
            }
            HttpPost httpPost = new HttpPost(url.toString());
            httpPost.setConfig(config);
            try {
                if (null != header) {
                    Set<Map.Entry<String, String>> entries = header.entrySet();
                    for (Map.Entry<String, String> entry : entries) {
                        httpPost.addHeader(entry.getKey(), entry.getValue());
                    }
                }
            } catch (Exception e) {
            }
//            httpPost.setEntity(new StringEntity(params));
//            httpPost.setEntity(new StringEntity(params, ContentType.APPLICATION_FORM_URLENCODED));
            StringEntity stringEntity = new StringEntity(params);
            stringEntity.setContentType("application/x-www-form-urlencoded");
            httpPost.setEntity(stringEntity);
            CloseableHttpResponse response = null;
            try {
                response = httpclient.execute(target, httpPost);
                if (response != null) {
                    HttpEntity resEntity = response.getEntity();
                    if (resEntity != null) {
                        result = EntityUtils.toString(resEntity, "UTF-8");
//                        System.out.printlninfo("===============================================【返回结果】==================================================");
//                        System.out.printlninfo("||  {}",result);
//                        System.out.printlninfo("===========================================================================================================");
                        resMap.put("res", result);
                    }
                    Header[] headerinfo = response.getAllHeaders();
                    resMap.put("headerinfo", headerinfo);
//                    System.out.printlninfo("===============================================【返回头部】==================================================");
//                    System.out.printlninfo("===========================================================================================================");
                }
            } catch (Exception e) {
                resMap.put("res", "error");
                System.out.println("Connection refused: connect:{}"+e.getMessage());
            } finally {
                try {
                    response.close();
                } catch (NullPointerException e) {
                    resMap.put("res", "error");
                    System.out.println("无响应结果");
                }
            }
        }catch (ConnectTimeoutException | SocketTimeoutException e) {
//            System.out.printlninfo("====请求超时=====");
            System.out.println("【POST请求异常1】---->"+e.getMessage());
            resMap.put("res", "error");
            return resMap;
        }catch (ClientProtocolException e) {
//            e.printStackTrace();
            System.out.println("【POST请求异常2】---->"+e.getMessage());
            resMap.put("res", "error");
            return resMap;
        } catch (IOException e) {
            System.out.println("【POST请求异常3】---->"+e.getMessage());
//            e.printStackTrace();
            resMap.put("res", "error");
            return resMap;
        }finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resMap;
    }


    /**
     * 创建SSL安全连接
     *
     * @return
     */
    private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
        SSLConnectionSocketFactory sslsf = null;
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
                    new TrustStrategy() {
                        public boolean isTrusted(X509Certificate[] chain, String authType) {
                            return true;
                        }
                    }).build();
            sslsf = new SSLConnectionSocketFactory(sslContext, new HostnameVerifier() {

                @Override
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }
            });
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        return sslsf;
    }
}
